import { checkAllCartApi, deleteCartApi, findCartListApi, insertCartApi, mergeLocalCartApi, updateCartApi } from '@/api/cart'

/**
 * 存储购物车商品列表数据
 */
export default {
  namespaced: true,
  // 1. 定义变量
  state: {
    list: []
  },
  getters: {
    /**
     * 对购物车商品列表list做计算：
     *  1. 有效商品列表=》无效商品（没库存或下架了）
        2. 选中的购物车商品列表
        3. 选中商品总价
        4. 购物车中有效商品是否是全部选中状态
     */
    // 有效商品列表
    validList: state => {
      // 根据item.isEffective值：true 留下 | false 去掉
      return state.list.filter(item => item.isEffective)
    },
    // 有效商品==选中的商品列表==
    /**
     *
     * @param {*} state 所有state变量
     * @param {*} getters getters计算属性所有变量
     */
    validSeledList (state, getters) {
      return getters.validList.filter(item => item.selected)
    },
    // 有效商品==选中的商品列表==所有商品总价
    /**
     * 单个商品价格计算：商品的现价nowPrice * 商品的数量count
     * == 有效的选中的商品的总价（validSeledList）：每个商品价格之和 ==
     * @param {*} state
     * @param {*} getters
     * @returns
     */
    validSeledListTotal (state, getters) {
      // 写法1：forEach实现
      // 1. 总价
      // let total = 0
      // getters.validSeledList.forEach(item => {
      //   // 2. 累加
      //   total += item.nowPrice * item.count
      // })
      // return total
      return getters.validSeledList.reduce((total, item) => total + item.nowPrice * item.count, 0)
    },
    // 有效商品是否是全部选中状态: true 全部选中 | false 未全部选中（至少有一个没有选中）
    validListSeledAll (state, getters) {
      /**
       * 1. every方法：所有都满足才返回true
       * 2. some方法：只要有一个满足就返回true
       */
      return getters.validList.every(item => item.selected)
    }

  },
  // state: () => ({
  //   list: []
  // }),
  // 2. 修改变量（同步）
  mutations: {
    /**
     * 存储后台查出来的购物车列表
     * @param {*} state
     * @param {*} list 后台查出来的购物车列表
     */
    setList (state, list) {
      state.list = list
    },
    /**
     * 加入购物车
     * @param {*} state
     * @param {*} skuGood
     */
    addCart (state, skuGood) {
      /**
       * 判断之前是否加入过该商品？（排重）
       * 1. 加入过：数量的增加
       * 2. 没有加入过：新增
       */
      // state.list 获取已经加入购物车商品
      /**
       * state.list.findIndex方法判断当前skuGood商品是否在list中：
       * 1. 存在：返回存在sku商品的索引值
       * 2. 不存在：返回-1
       */
      const index = state.list.findIndex((item) => item.skuId === skuGood.skuId)
      if (index === -1) {
        // 不存在=>添加到数组的第一个位置
        state.list.unshift(skuGood)
      } else {
        // 存在=>  state.list[index]获取当前已经存在商品，进行数量增加
        state.list[index].count += skuGood.count
      }
    },
    /**
     *
     * @param {*} state
     * @param {*} { good:当前勾选的商品, sel:当前商品的勾选状态 }
     */
    singleSel (state, { good, sel }) {
      /**
       * 1. 在state.list中找到要修改的商品
       * 2. 修改商品的选中
       */
      const currGood = state.list.find((item) => item.skuId === good.skuId)
      currGood.selected = sel
    },
    /**
     *
     * @param {*} state
     * @param {*} isSelAll 全选框选中的boolean值
     */
    selAll (state, isSelAll) {
      /**
       * 全选和取消全选：
       * 如果全选框：
       * 1. 选中true：列表全部选中
       * 2. 未选中false：列表全部取消选中
       */
      state.list.forEach(item => {
        // 每个商品的选中和全选框选中的值一样的
        item.selected = isSelAll
      })
    },
    /**
     *
     * @param {*} state
     * @param {*} good 当前要删除的商品
     */
    delCart (state, good) {
      // filter:排除good商品
      state.list = state.list.filter(item => item.skuId !== good.skuId)
    },
    /**
     * 数量修改
     * @param {*} state
     * @param {*} param1
     */
    changeNum (state, { good, num }) {
      const currGood = state.list.find((item) => item.skuId === good.skuId)
      currGood.count = num
    }
  },
  // 3. 发送请求（异步）
  actions: {
    async mergeCartAction ({ state, dispatch }) {
      /**
       * 需求：把之前未登录的时候，存到本地购物车商品列表，合并到当前登录人
       * 名下，存到数据库
       * 流程：
       * 1. 获取本地购物车商品列表数据=》ctx.state
       * 2. 判断未登录的时候，本地有没有存储购物车数据
       *    有存储=》调用后台接口，执行合并
       * 3. 调用接口查询购物车最新的数据存到vuex=》渲染显示
       */
      if (state.list.length > 0) {
        // 本地有存储购物车数据=>调用后台接口，执行合并
        // 1. 获取后台需要的待合并的购物车列表数据
        const mergeData = state.list.map((item) => {
          return {
            skuId: item.skuId,
            selected: item.selected,
            count: item.count
          }
        })
        console.log('后台需要的待合并的购物车列表数据:', mergeData)
        await mergeLocalCartApi(mergeData)
      }

      // == 调用接口查询=>登录人购物车最新的数据存到vuex=》渲染显示 ==
      dispatch('getCartListAction')
    },
    /**
     * 从数据库查询=》当前登录人的 =》最新的购物车列表数据
     * @param {*} param0
     */
    async getCartListAction ({ commit }) {
      const { data } = await findCartListApi()
      console.log('登录人的购物车列表：', data)
      commit('setList', data)
    },
    /**
     *
     * @param {*} param0
     * @param {*} skuGood 当前加入购物车的sku组合商品
     * @return Promise对象
     * 购物车逻辑：
     * 问题?怎么判断是否登录
     * 1. 未登录（今天）
     * 数据存到vuex（不需要调用后台接口）
     *
     * 2. 已经登录
     * 数据存到数据库（需要调用后台接口）
     */
    async addCartAction ({ commit, rootState, dispatch }, skuGood) {
      // 问题?怎么判断是否登录 =》根据是否有token
      // console.log('action上下文ctx：', ctx)
      if (rootState.user.profile.token) {
        // 已经登录
        console.log('已登录')
        // 1. 调用加入购物车接口
        await insertCartApi(skuGood)
        // 2. 从数据 查询最新购物车数据
        dispatch('getCartListAction')
      } else {
        // 未登录（今天）
        console.log('未登录-新增的sku商品信息：', skuGood)
        // 调用mucations方法加入购物车
        commit('addCart', skuGood)
        // 主动抛出错误
        // throw new Error('出错了！')
      }
      return '加入购物车成功'
    },
    /**
     * 商品单选
     * @param {*} param0
     * @param {*} skuGood
     * @returns
     */
    async singleSelAction ({ commit, rootState, dispatch }, { good, sel }) {
      // 问题?怎么判断是否登录 =》根据是否有token
      // console.log('action上下文ctx：', ctx)
      if (rootState.user.profile.token) {
        // 已经登录
        console.log('已登录')
        // 说明❓：后边加入的selected属性值会覆盖前边good中selected值
        await updateCartApi({ ...good, selected: sel })
        dispatch('getCartListAction')
      } else {
        // 未登录
        commit('singleSel', { good, sel })
      }
    },
    // 全选
    async selAllAction ({ commit, rootState, dispatch, getters }, isSelAll) {
      // 问题?怎么判断是否登录 =》根据是否有token
      // console.log('action上下文ctx：', ctx)
      if (rootState.user.profile.token) {
        // 已经登录
        console.log('已登录')
        // 有效商品skuId数组
        const ids = getters.validList.map(item => item.skuId)
        await checkAllCartApi({ selected: isSelAll, ids })
        dispatch('getCartListAction')
      } else {
        // 未登录
        commit('selAll', isSelAll)
      }
    },
    // 删除
    /**
     *
     * @param {*} param0
     * @param {*} good 当前删除商品
     */
    async delCartAction ({ dispatch, commit, rootState }, good) {
      // 问题?怎么判断是否登录 =》根据是否有token
      // console.log('action上下文ctx：', ctx)
      if (rootState.user.profile.token) {
        // 已经登录
        console.log('已登录')
        await deleteCartApi([good.skuId])
        dispatch('getCartListAction')
      } else {
        // 未登录
        commit('delCart', good)
      }
    },
    /**
     *
     * @param {*} param0
     * @param {*} good 修改数量的商品  num 修改的数量
     */
    async changeNumAction ({ dispatch, commit, rootState, state }, { good, num }) {
      // 问题?怎么判断是否登录 =》根据是否有token
      // console.log('action上下文ctx：', ctx)
      if (rootState.user.profile.token) {
        // 已经登录
        console.log('已登录')
        await updateCartApi({ ...good, count: num })
        dispatch('getCartListAction')
      } else {
        // 未登录
        console.log('当前模块数据：', state)
        commit('changeNum', { good, num })
      }
    }
  }
}
